package com.xhj.mybatis.util;

import java.util.AbstractMap;
import java.util.Map;
import java.util.function.Function;

/**
 * MapUtil
 *
 * @author XJks
 * @description Map 工具类
 */
public class MapUtil {
    /**
     * 如果指定的 key 在 map 中不存在，则使用 mappingFunction 生成 value 并插入 map，然后返回该 value。
     * 如果 key 已经存在，则直接返回对应的 value。
     *
     * @param map             要操作的 Map
     * @param key             要查找或插入的键
     * @param mappingFunction 当 key 不存在时，用于生成 value 的函数
     * @param <K>             键类型
     * @param <V>             值类型
     * @return key 对应的值
     */
    public static <K, V> V computeIfAbsent(Map<K, V> map, K key, Function<K, V> mappingFunction) {
        // 从 map 中获取 key 对应的值，可能为 null（表示 key 不存在）
        V value = map.get(key);
        // 如果 value 不为 null，说明 key 已经存在，直接返回该值
        if (value != null) {
            return value;
        }
        // 如果 value 为 null，说明 key 不存在，调用 map 的 computeIfAbsent 方法。
        // 如果 key 不存在，则用 mappingFunction 生成 value，并插入 map。
        // mappingFunction::apply 是方法引用，等价于 k -> mappingFunction.apply(k)。
        return map.computeIfAbsent(key, mappingFunction::apply);
    }

    /**
     * Java 8 下 Map.entry(key, value) 的替代方法。
     * 该方法用于创建一个不可变的键值对（Entry），常用于流操作或需要临时键值对的场景。
     *
     * @param key   要放入 Entry 的键
     * @param value 要放入 Entry 的值
     * @param <K>   键的类型
     * @param <V>   值的类型
     * @return 一个不可变的 Map.Entry 对象，包含给定的 key 和 value
     */
    public static <K, V> Map.Entry<K, V> entry(K key, V value) {
        // 创建一个不可变的键值对对象（SimpleImmutableEntry），这样 Entry 的 key 和 value 不能被修改
        return new AbstractMap.SimpleImmutableEntry<>(key, value);
    }

    /**
     * 私有构造方法，防止外部实例化该工具类
     */
    private MapUtil() {
        // 调用父类构造方法（Object），这里其实可以省略
        super();
    }
}
